﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MegaBitProject.Models;
using MegaBitProject.ViewModels;

namespace MegaBitProject.Controllers
{
    [Authorize]
    public class PictionaryController : Controller
    {
        //
        // GET: /Pictionary/

        private IGameRepository rep = null;


        public PictionaryController()
        {
            rep = new GameRepository();
        }

        public PictionaryController(IGameRepository _rep)
        {
            rep = _rep;
        }

        //Gets the Pictioanry Application (chat access)
        public ActionResult Lobby()
        {
            var model = (from g in rep.getGames
                         where g.ID == 2
                         select g).SingleOrDefault();

            return View(model);
        }


       // pick an open game by ID if its available,  calls ActionResult Join
        public ActionResult Random()
        {
            PlayedGame g = new PlayedGame(); 
            g.gameID = (from game in rep.getOpenGames
                        join u in rep.getUser on game.userID equals u
                        where game.userID.UserName.ToLower() != User.Identity.Name.ToLower()
                        select game).LastOrDefault();
             
            if (g.gameID != null)
            {
                g.userID = (from user in rep.getUser
                            where user.UserName.ToLower() == User.Identity.Name.ToLower()
                            select user).SingleOrDefault();
                g.score = 0;
                g.timeStamp = DateTime.Now;

                return Join(g.gameID.ID);
            }

            return RedirectToAction("Lobby");
           
        }
        // Places the user in the game with the games ID as parameter
        public ActionResult Game(int? id)
        {

            if (id.HasValue)
            {
                int nid = Convert.ToInt32(id);

                Pictionary model = new Pictionary();
                
                model = (from p in rep.getPictionary
                         join g in rep.getOpenGames on p.gameID.ID equals g.ID
                         join u in rep.getUser on p.userID.UserId equals u.UserId
                         where p.gameID.ID == nid
                         select p).SingleOrDefault();

                //var usern = (from user in rep.getUser
                //             where user.UserName.ToString().ToLower() == User.Identity.Name.ToLower()
                //             select user).SingleOrDefault();

                //var uesringame = (from p in rep.getPlayedGames
                //                  join g in rep.getOpenGames on p.gameID equals g
                //                  where g.ID == nid && g.userID.UserName.ToString().ToLower() == User.Identity.Name.ToString().ToLower()
                //                  select p).SingleOrDefault();

                //if (model != null && uesringame != null)
                if (model != null)
                {
                    return View(model);
                }
                else
                {
                    return RedirectToAction("Lobby");
                }
            }
            else
            {
                return RedirectToAction("Lobby");
            }
        }

        [HttpGet]
        public ActionResult Create()
        {
            return View();
        }


        // Creates an instance of Pictionary
        [HttpPost]
        public ActionResult Create(FormCollection formData)
        {
            Game g = new Game();
            Pictionary p = new Pictionary();

            g.appID = (from game in rep.getGames
                       where game.ID == 2
                       select game).SingleOrDefault();

            g.minPlayers = 2;
            g.time = DateTime.Now;
            g.userID = (from user in rep.getUser
                        where user.UserName.ToString().ToLower() == (User.Identity.Name).ToLower()
                        select user).SingleOrDefault();

            UpdateModel(g);
            rep.newGame(g);

            // Picks a random word
            int maxNum = (from max in rep.getWord
                          select max.ID).Max();
            Random rnd = new Random();
            int rand = rnd.Next(1, maxNum + 1);
            p.word = (from word in rep.getWord
                        where word.ID == rand
                        select word.Word).SingleOrDefault().ToString();

            p.gameID = (from u in rep.getOpenGames
                        where u.userID == g.userID && u.appID == g.appID
                        select u).Last();
            
            p.userID = g.userID;

            p.session = 1;
            
            UpdateModel(p);
            rep.newPictionary(p);

            return Join(g.ID);
        }

        // Accepts game ID as parameter, joins user game with the ID
        //redirects to ActionResult game with game ID
        public ActionResult Join(int? id)
        {
            if (id != null)
            {
                int nid = Convert.ToInt32(id);

                var uesringame = (from p in rep.getPlayedGames
                                  join g in rep.getOpenGames on p.gameID.ID equals g.ID
                                  join u in rep.getUser on p.userID.UserId equals u.UserId
                                  where g.ID == nid && g.userID == u && u.UserName.ToLower() == User.Identity.Name.ToLower()
                                  select p).SingleOrDefault();
                
                if (uesringame == null)
                {
                    PlayedGame g = new PlayedGame();
                    g.gameID = (from game in rep.getOpenGames
                                where game.ID == nid
                                select game).SingleOrDefault();

                    var counter = (from game in rep.getPlayedGames
                                   where game.gameID == g.gameID
                                   select game).Count();

                    if (g.gameID != null && counter < g.gameID.maxPlayers)
                    {
                        g.userID = (from user in rep.getUser
                                     where (user.UserName).ToString().ToLower() == User.Identity.Name.ToLower()
                                     select user).SingleOrDefault();

                        g.score = 0;
                        g.timeStamp = DateTime.Now;

                        UpdateModel(g);
                        rep.joinGame(g);

                        return RedirectToAction("Game/" + nid);
                    }
                    else
                    {
                        return RedirectToAction("Lobby");
                    }
                }
                else
                {
                    return RedirectToAction("Game/" + nid);
                }
            }
            else
            {
                return RedirectToAction("Lobby");
            }
        }

        //A list of current Pictionary games returned as a partial view in lobby
        public ActionResult _CurrentGames()
        {
            CurrentGames view = new CurrentGames();

            view.id = new List<int>();
            view.maxPlayers = new List<int>();
            view.name = new List<string>();
            view.numPlayers = new List<int>();
            view.controller = new List<string>();

            var games = (from game in rep.getOpenGames
                         join app in rep.getGames
                         on game.appID equals app
                         where app.ID == 2
                         orderby game.ID descending
                         select game).ToList();

            foreach (var g in games)
            {
                var numP = (from game in rep.getPlayedGames
                            where game.gameID == g
                            select game).Count();

                var maxP = (from game in rep.getOpenGames
                            where game == g
                            select game).SingleOrDefault();

                if (numP < maxP.maxPlayers)
                {
                    view.numPlayers.Add(numP);
                    view.maxPlayers.Add(maxP.maxPlayers);
                    var name = (from game in rep.getGames
                                where game == maxP.appID
                                select game).SingleOrDefault();

                    view.name.Add(name.name);
                    view.id.Add(maxP.ID);
                    view.controller.Add(name.controller);
                }
            }

            return PartialView(view);
        }
    }
}